package edu.cmich.cps.cps240.partyprincesspalace.hw06;

import java.awt.event.KeyEvent;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import java.awt.event.MouseEvent;
import java.awt.Event;
import java.awt.BorderLayout;

import javax.swing.SwingConstants;
import javax.swing.SwingUtilities;
import javax.swing.KeyStroke;
import java.awt.Point;

import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JMenuItem;
import javax.swing.JMenuBar;
import javax.swing.JMenu;
import javax.swing.JFrame;
import javax.swing.JDialog;

import javax.swing.JScrollPane;

import java.awt.GridLayout;


/**
 * Main javax.swing application which contains all of the high level
 * GUI logic, such as sorting out event handlers, and setting up the
 * Workspace and Toolbox
 * @author holde1ja
 */

//	Test comment
public class GUI {

	private JFrame jFrame = null;  //  @jve:decl-index=0:visual-constraint="10,45"
	private JPanel jContentPane = null;
	private JMenuBar jMenuBar = null;
	private JMenu fileMenu = null;
	private JMenu editMenu = null;
	private JMenu helpMenu = null;
	private JMenuItem exitMenuItem = null;
	private JMenuItem aboutMenuItem = null;
	private JMenuItem cutMenuItem = null;
	private JMenuItem copyMenuItem = null;
	private JMenuItem pasteMenuItem = null;
	private JMenuItem saveMenuItem = null;
	private JMenuItem loadMenuItem = null;
	private JMenuItem SaveHDLMenuItem = null;
	private JMenuItem customChipMenuItem = null;
	private JDialog aboutDialog = null;  //  @jve:decl-index=0:visual-constraint="546,44"
	private JPanel aboutContentPane = null;
	private JLabel aboutVersionLabel = null;
	private JScrollPane scrollableToolbox = null;
	private Workspace workspace = null;
	private Toolbox toolbox = null;
	private JScrollPane scrollableWorkspace = null;
	
	/**
	 * If you do not specify a constructor, a default one
	 * will be provided for you
	 */
	public GUI()
	{
		super();
	}
	
	/**
	 * This method initializes jFrame
	 * 
	 * @return javax.swing.JFrame
	 */
	private JFrame getJFrame() {
		if (jFrame == null) {
			jFrame = new JFrame();
			jFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
			jFrame.setJMenuBar(getJMenuBar());
			jFrame.setSize(517, 338);
			jFrame.setContentPane(getJContentPane());
			jFrame.setTitle("Application");
		}
		return jFrame;
	}

	/**
	 * This method initializes jContentPane
	 * 
	 * @return javax.swing.JPanel
	 */
	private JPanel getJContentPane() {
		if (jContentPane == null) {
			jContentPane = new JPanel();
			jContentPane.setLayout(new BorderLayout());
			jContentPane.add(getScrollableToolbox(), BorderLayout.WEST);
			jContentPane.add(getScrollableWorkspace(), BorderLayout.CENTER);
		}
		return jContentPane;
	}

	/**
	 * This method initializes jJMenuBar	
	 * 	
	 * @return javax.swing.JMenuBar	
	 */
	private JMenuBar getJMenuBar() {
		if (jMenuBar == null) {
			jMenuBar = new JMenuBar();
			jMenuBar.add(getFileMenu());
			jMenuBar.add(getEditMenu());
			jMenuBar.add(getHelpMenu());
		}
		return jMenuBar;
	}

	/**
	 * This method initializes jMenu	
	 * 	
	 * @return javax.swing.JMenu	
	 */
	private JMenu getFileMenu() {
		if (fileMenu == null) {
			fileMenu = new JMenu();
			fileMenu.setText("File");
			fileMenu.add(getSaveMenuItem());
			fileMenu.add(getLoadMenuItem());
			fileMenu.addSeparator();
			fileMenu.add(getSaveHDLMenuItem());
			fileMenu.add(getCustomChipFromHDLItem());
			fileMenu.addSeparator();
			fileMenu.add(getExitMenuItem());
		}
		return fileMenu;
	}
	
	private JMenuItem getCustomChipFromHDLItem(){
		if (customChipMenuItem == null) {
			customChipMenuItem = new JMenuItem();
			customChipMenuItem.setText("Create a Custom chip from HDL (NOT FUNCTIONAL)");
			customChipMenuItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_U,
					Event.CTRL_MASK, true));
			
			/*
			 * This functionality was not completed on time, I am commenting it out for now
			customChipMenuItem.addActionListener(new ActionListener() {
				public void actionPerformed(ActionEvent e) {
					workspace.HDLtoCChip();
					// Code to open an HDL file and make a custom chip.
					workspace.repaint();
				}
			});
			*/
		}
		return customChipMenuItem;
	}
	
	/**
	 * Why am I the only one who goes through here and writes comments for these things?
	 * Returns the "Load" JMenuItem which loads a file of serialized objects (IE, NOT HDL)
	 * @return the "load" menu item
	 */
	private JMenuItem getLoadMenuItem() {
		if (loadMenuItem == null) {
			loadMenuItem = new JMenuItem();
			loadMenuItem.setText("Load");
			loadMenuItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_O,
					Event.CTRL_MASK, true));
			loadMenuItem.addActionListener(new ActionListener() {
				public void actionPerformed(ActionEvent e) {
					System.out.println("Load");
					workspace.fileToProject();
					workspace.repaint();
				}
			});
		}
		return loadMenuItem;
	}
	
	/**
	 * Returns the "save" JMenuItem which saves a file of serialized objects (IE, NOT HDL)
	 * @return the "save" menu item
	 */
	private JMenuItem getSaveHDLMenuItem() {
		if (SaveHDLMenuItem == null) {
			SaveHDLMenuItem = new JMenuItem();
			SaveHDLMenuItem.setText("Save HDL");
			SaveHDLMenuItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_H,
					Event.CTRL_MASK, true));
			SaveHDLMenuItem.addActionListener(new ActionListener() {
				public void actionPerformed(ActionEvent e) {
					System.out.println("Save HDL");
					workspace.projectToHDL();
				}
			});
		}
		return SaveHDLMenuItem;
	}
	
	/**
	 * This method initializes jMenu	
	 * 	
	 * @return javax.swing.JMenu	
	 */
	private JMenu getEditMenu() {
		if (editMenu == null) {
			editMenu = new JMenu();
			editMenu.setText("Edit");
			editMenu.add(getCutMenuItem());
			editMenu.add(getCopyMenuItem());
			editMenu.add(getPasteMenuItem());
		}
		return editMenu;
	}

	/**
	 * This method initializes jMenu	
	 * 	
	 * @return javax.swing.JMenu	
	 */
	private JMenu getHelpMenu() {
		if (helpMenu == null) {
			helpMenu = new JMenu();
			helpMenu.setText("Help");
			helpMenu.add(getAboutMenuItem());
		}
		return helpMenu;
	}

	/**
	 * This method initializes jMenuItem	
	 * 	
	 * @return javax.swing.JMenuItem	
	 */
	private JMenuItem getExitMenuItem() {
		if (exitMenuItem == null) {
			exitMenuItem = new JMenuItem();
			exitMenuItem.setText("Exit");
			exitMenuItem.addActionListener(new ActionListener() {
				public void actionPerformed(ActionEvent e) {
					System.exit(0);
				}
			});
		}
		return exitMenuItem;
	}

	/**
	 * This method initializes jMenuItem	
	 * 	
	 * @return javax.swing.JMenuItem	
	 */
	private JMenuItem getAboutMenuItem() {
		if (aboutMenuItem == null) {
			aboutMenuItem = new JMenuItem();
			aboutMenuItem.setText("About");
			aboutMenuItem.addActionListener(new ActionListener() {
				public void actionPerformed(ActionEvent e) {
					JDialog aboutDialog = getAboutDialog();
					aboutDialog.pack();
					Point loc = getJFrame().getLocation();
					loc.translate(20, 20);
					aboutDialog.setLocation(loc);
					aboutDialog.setVisible(true);
				}
			});
		}
		return aboutMenuItem;
	}

	/**
	 * This method initializes aboutDialog	
	 * 	
	 * @return javax.swing.JDialog
	 */
	private JDialog getAboutDialog() {
		if (aboutDialog == null) {
			aboutDialog = new JDialog(getJFrame(), true);
			aboutDialog.setTitle("About");
			aboutDialog.setContentPane(getAboutContentPane());
		}
		return aboutDialog;
	}

	/**
	 * This method initializes aboutContentPane
	 * 
	 * @return javax.swing.JPanel
	 */
	private JPanel getAboutContentPane() {
		if (aboutContentPane == null) {
			aboutContentPane = new JPanel();
			aboutContentPane.setLayout(new BorderLayout());
			aboutContentPane.add(getAboutVersionLabel(), BorderLayout.CENTER);
		}
		return aboutContentPane;
	}

	/**
	 * This method initializes aboutVersionLabel	
	 * 	
	 * @return javax.swing.JLabel	
	 */
	private JLabel getAboutVersionLabel() {
		if (aboutVersionLabel == null) {
			aboutVersionLabel = new JLabel();
			aboutVersionLabel.setText("Version 1.0");
			aboutVersionLabel.setHorizontalAlignment(SwingConstants.CENTER);
		}
		return aboutVersionLabel;
	}

	/**
	 * This method initializes jMenuItem	
	 * 	
	 * @return javax.swing.JMenuItem	
	 */
	private JMenuItem getCutMenuItem() {
		if (cutMenuItem == null) {
			cutMenuItem = new JMenuItem();
			cutMenuItem.setText("Cut");
			cutMenuItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_X,
					Event.CTRL_MASK, true));
		}
		return cutMenuItem;
	}

	/**
	 * This method initializes jMenuItem	
	 * 	
	 * @return javax.swing.JMenuItem	
	 */
	private JMenuItem getCopyMenuItem() {
		if (copyMenuItem == null) {
			copyMenuItem = new JMenuItem();
			copyMenuItem.setText("Copy");
			copyMenuItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_C,
					Event.CTRL_MASK, true));
		}
		return copyMenuItem;
	}

	/**
	 * This method initializes jMenuItem	
	 * 	
	 * @return javax.swing.JMenuItem	
	 */
	private JMenuItem getPasteMenuItem() {
		if (pasteMenuItem == null) {
			pasteMenuItem = new JMenuItem();
			pasteMenuItem.setText("Paste");
			pasteMenuItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_V,
					Event.CTRL_MASK, true));
		}
		return pasteMenuItem;
	}

	/**
	 * This method initializes jMenuItem	
	 * 	
	 * @return javax.swing.JMenuItem	
	 */
	private JMenuItem getSaveMenuItem() {
		if (saveMenuItem == null) {
			saveMenuItem = new JMenuItem();
			saveMenuItem.setText("Save");
			saveMenuItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_S,
					Event.CTRL_MASK, true));
			saveMenuItem.addActionListener(new ActionListener() {
				public void actionPerformed(ActionEvent e) {
					System.out.println("Save");
					workspace.projectToFile();
				}
			});

		}
		return saveMenuItem;
	}

	/**
	 * This method initializes toolbox	
	 * 	
	 * @return javax.swing.JScrollPane	
	 */
	private JScrollPane getScrollableToolbox() {
		if (scrollableToolbox == null) {
			scrollableToolbox = new JScrollPane();
			scrollableToolbox.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
			scrollableToolbox.setName("scrollableToolbox");
			scrollableToolbox.add(getToolbox());
			scrollableToolbox.setViewportView(getToolbox());
		}
		return scrollableToolbox;
	}
	
	/**
	 * Initialises the toolbox if needed, and returns it
	 * @return The toolbox object
	 */
	private Toolbox getToolbox()
	{
		if (toolbox == null)
		{
			toolbox = new Toolbox(getWorkspace());
		}
		return toolbox;
	}

	/**
	 * This method initializes workspace	
	 * 	
	 * @return javax.swing.JPanel	
	 */
	private Workspace getWorkspace() {
		if (workspace == null) {
			GridLayout gridLayout1 = new GridLayout();
			gridLayout1.setRows(1);
			gridLayout1.setHgap(0);
			gridLayout1.setVgap(0);
			workspace = new Workspace();
			workspace.setLayout(gridLayout1);
			workspace.addMouseListener(new java.awt.event.MouseAdapter() {
				public void mouseClicked(java.awt.event.MouseEvent e) {
					if(e.getButton() == MouseEvent.BUTTON1){
						workspace.wasClicked(e.getPoint());
					}
				}

				
				public void mousePressed(MouseEvent e) {
					if(e.getButton() == MouseEvent.BUTTON1){
						workspace.startDragging(e.getPoint());
					}
				}
				
				public void mouseReleased(MouseEvent e){
					workspace.endDrag(e.getPoint());
				}
			});

			workspace.addMouseMotionListener(new java.awt.event.MouseMotionAdapter() {
				public void mouseDragged(java.awt.event.MouseEvent e) {
					int dragMask = MouseEvent.BUTTON1_DOWN_MASK;
					if((e.getModifiersEx() & dragMask) == dragMask){
						((Workspace)e.getSource()).dragging(e.getPoint());
						workspace.repaint();
					}
				}
			});
		}
		return workspace;
	}

	/**
	 * This method initializes scrollableWorkspace	
	 * 	
	 * @return javax.swing.JScrollPane	
	 */
	private JScrollPane getScrollableWorkspace() {
		if (scrollableWorkspace == null) {
			scrollableWorkspace = new JScrollPane();
			scrollableWorkspace.setViewportView(getWorkspace());
		}
		return scrollableWorkspace;
	}

	/**
	 * Launches this application
	 */
	public static void main(String[] args) {
		SwingUtilities.invokeLater(new Runnable() {
			public void run() {
				GUI application = new GUI();
				application.getJFrame().setVisible(true);
			}
		});
	}

}
